home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 February
/
EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso
/
enigma
/
earcd
/
emula
/
msh-156.lha
/
util
/
fmtmain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-22
|
22KB
|
1,015 lines
/*-
* $Id: fmtmain.c,v 1.56 1996/12/22 00:22:33 Rhialto Rel $
* $Log: fmtmain.c,v $
* Revision 1.56 1996/12/22 00:22:33 Rhialto
* Cosmetics.
*
* Revision 1.55 1993/12/30 23:28:00 Rhialto
* Freeze for MAXON5.
* New GadToolBox (2.0c), and use font-sensitive option.
*
* Revision 1.54 1993/06/24 05:35:45 Rhialto
* changing SPT,NSIDES,NCYLS didn't update SPF.
* DICE 2.07.54R.
*
* Revision 1.53 92/10/25 02:48:07 Rhialto
* Initial revision.
*
* FMT MAIN.C
*
* The main file of the MSH formatting utility.
*
* This code is (C) Copyright 1992 by Olaf Seibert. All rights reserved.
* May not be used or copied without a licence.
-*/
#define INTUI_V36_NAMES_ONLY
#include "han.h"
#ifndef LIBRARIES_GADTOOLS_H
#include <libraries/gadtools.h>
#endif
#ifndef INTUITION_GADGETCLASS_H
#include <intuition/gadgetclass.h>
#endif
#ifndef DOS_DOS_H
#include <dos/dos.h>
#endif
#ifndef DOS_DOSEXTENS_H
#include <dos/dosextens.h>
#endif
#ifndef DOS_FILEHANDLER_H
#include <dos/filehandler.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include "fmtwindow.h"
struct Library *GadToolsBase;
struct IntuituinBase *IntuitionBase;
struct MinList MSHList;
struct MSHNode {
struct Node m_Node;
struct DosList *m_DosList;
char m_Name[2]; /* 1 for ':', 1 for '\0' */
};
struct DosList *HandlerDList;
char *HandlerName;
char *DevName;
long DevUnit;
unsigned long DevFlags;
const char OkString[] = "Ok";
const char AbortString[] = "Abort";
const char PanicString[] = "Panic!";
const char RCSId[] = "\0$\VER: MSH-Format $Revision: 1.56 $ $Date: 1996/12/22 00:22:33 $, by Olaf Seibert";
void Show(void);
void Hide(void);
void HideParm(void);
void SetGadgetAttrM(int id, ULONG tag, ULONG value);
void SetGadgetAttrP(int id, ULONG tag, ULONG value);
void SetStringDefaults(void);
void UpdateStrings(void);
#define DONE_DONE 1
#define DONE_RESET 2
#define DONE_HIDEP 4
const ulong BootBlock[] = {
0xEB349049, 0x424D2020, 0x332E3200, 0x02020100, /* ...IBM 3.2..... */
0x027000A0, 0x05F90300, 0x09000200, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x0000000F,
0x00000000, 0x0100FA33, 0xC08ED0BC, 0x007C1607,
0xBB780036, 0xC5371E56, 0x1653BF2B, 0x7CB90B00,
0xFCAC2680, 0x3D007403, 0x268A05AA, 0x8AC4E2F1,
0x061F8947, 0x02C7072B, 0x7CFBCD13, 0x7267A010,
0x7C98F726, 0x167C0306, 0x1C7C0306, 0x0E7CA33F,
0x7CA3377C, 0xB82000F7, 0x26117C8B, 0x1E0B7C03,
0xC348F7F3, 0x0106377C, 0xBB0005A1, 0x3F7CE896,
0x00B80102, 0xE8AA0072, 0x198BFBB9, 0x0B00BECD,
0x7DF3A675, 0x0D8D7F20, 0xBED87DB9, 0x0B00F3A6,
0x7418BE6E, 0x7DE86100, 0x32E4CD16, 0x5E1F8F04,
0x8F4402CD, 0x19BEB77D, 0xEBEBA11C, 0x0533D2F7,
0x360B7CFE, 0xC0A23C7C, 0xA1377CA3, 0x3D7CBB00,
0x07A1377C, 0xE84000A1, 0x187C2A06, 0x3B7C4050,
0xE84E0058, 0x72CF2806, 0x3C7C760C, 0x0106377C,
0xF7260B7C, 0x03D8EBD9, 0x8A2E157C, 0x8A16FD7D,
0x8B1E3D7C, 0xEA000070, 0x00AC0AC0, 0x7422B40E,
0xBB0700CD, 0x10EBF233, 0xD2F73618, 0x7CFEC288,
0x163B7C33, 0xD2F7361A, 0x7C88162A, 0x7CA3397C,
0xC3B4028B, 0x16397CB1, 0x06D2E60A, 0x363B7C8B,
0xCA86E98A, 0x16FD7D8A, 0x362A7CCD, 0x13C30D0A,
0x4E6F6E2D, 0x53797374, 0x656D2064, 0x69736B20, /* Non-System disk */
0x6F722064, 0x69736B20, 0x6572726F, 0x720D0A52, /* or disk error..R */
0x65706C61, 0x63652061, 0x6E642073, 0x7472696B, /* eplace and strik */
0x6520616E, 0x79206B65, 0x79207768, 0x656E2072, /* e any key when r */
0x65616479, 0x0D0A000D, 0x0A446973, 0x6B20426F, /* eady.....Disk Bo */
0x6F742066, 0x61696C75, 0x72650D0A, 0x0049424D, /* ot failure...IBM */
0x42494F20, 0x20434F4D, 0x49424D44, 0x4F532020, /* BIO COMIBMDOS */
0x434F4D00, 0x00000000, 0x00000000, 0x00000000, /* COM............. */
0x00000000, 0x00000000, 0x00000000, 0x000055AA,
};
byte *DiskTrack;
long TrackSize;
int Track;
int EndTrack;
struct IOExtTD *TDReq;
int Break;
int Parameters[13];
int FormatWhat;
#define BOOT_ONLY 0
#define BOOT_ROOT 1
#define WHOLE_DISK 2
#define BPS Parameters[GDX_BPS]
#define SPT Parameters[GDX_SPT]
#define NSIDES Parameters[GDX_NSIDES]
#define FIRSTCYL Parameters[GDX_FIRSTCYL]
#define NCYLS Parameters[GDX_NCYLS]
#define SPC Parameters[GDX_SPC]
#define RESERVED Parameters[GDX_RESERVED]
#define NFATS Parameters[GDX_NFATS]
#define NDIRS Parameters[GDX_NDIRS]
#define NSECTS Parameters[GDX_NSECTS]
#define MEDIA Parameters[GDX_MEDIA]
#define SPF Parameters[GDX_SPF]
#define NHID Parameters[GDX_NHID]
int
todigit(char c)
{
if ((c -= '0') < 0 || c > ('F' - '0'))
return 42;
if (c >= ('A' - '0')) {
c -= 'A' - '9' - 1;
}
return c;
}
long
ntoi(char *str)
{
long total = 0;
long value;
int digit;
int base;
/* First determine the base */
number:
if (*str == '0') {
if (*++str == 'x') { /* 0x means hexadecimal */
base = 16;
str++;
} else {
base = 8; /* Otherwise, 0 means octal */
}
} else {
base = 10; /* and any other digit means decimal */
}
value = 0;
while ((digit = todigit(*str)) < base) {
value *= base;
value += digit;
str++;
}
suffix:
switch (*str++) {
case 'm': /* scale with megabytes */
value *= 1024L * 1024;
goto suffix;
case 'k': /* scale with kilobytes */
value *= 1024;
goto suffix;
case 's': /* scale with sectors */
value *= TD_SECTOR; /* or maybe even kilosectors! */
goto suffix;
case 'b': /* scale with bytes */
goto suffix;
}
str--;
total += value;
if (*str >= '0' && *str <= '9')
goto number; /* Allow 10k512, recursion eliminated */
return total;
}
char *
iton(char *string, int size, int value)
{
if (value >= 1024 * 1024L) {
int m;
int rest;
char *last;
m = value / (1024 * 1024L);
rest = value - (m * 1024L * 1024);
last = iton(string, size, m);
*last++ = 'm';
size -= (last - string);
value = rest;
string = last;
}
if (value >= 64 * 1024) {
int k;
int rest;
char *last;
k = value / 1024;
rest = value - (k * 1024);
last = iton(string, size, k);
*last++ = 'k';
size -= (last - string);
value = rest;
string = last;
}
sprintf(string, "%d", value);
while (*string)
string++;
return string;
}
void
PutWord(byte *address, word value)
{
address[0] = value;
address[1] = value >> 8;
}
void
Die(void)
{
Hide();
if (IntuitionBase) {
CloseLibrary(IntuitionBase);
IntuitionBase = NULL;
}
if (GadToolsBase) {
CloseLibrary(GadToolsBase);
GadToolsBase = NULL;
}
exit(0);
}
void
OpenAll(int argc, char **argv)
{
extern struct Library *DOSBase;
NewList((struct List *) &MSHList);
if (DOSBase->lib_Version < 37) {
puts("Sorry, requires at least V37...");
Die();
}
GadToolsBase = OpenLibrary("gadtools.library", 37L);
if (!GadToolsBase)
Die();
IntuitionBase = OpenLibrary("intuition.library", 37L);
if (!IntuitionBase)
Die();
Show();
}
int
isFileSystem(struct MsgPort *handler)
{
if (handler == NULL)
return FALSE;
if (DoPkt(handler, ACTION_IS_FILESYSTEM, 0, 0, 0, 0, 0)) {
return TRUE;
}
return FALSE;
}
void
FindAllDevices(void)
{
struct DosList *dlist;
dlist = LockDosList(LDF_DEVICES | LDF_READ);
while (dlist = NextDosEntry(dlist, LDF_DEVICES)) {
if (dlist->dol_misc.dol_handler.dol_Startup > 100 &&
isFileSystem(dlist->dol_Task)) {
char *name;
struct MSHNode *node;
name = (char *) BADDR(dlist->dol_Name);
node = AllocVec(sizeof (*node) + name[0], MEMF_CLEAR);
if (node) {
strncpy(node->m_Name, &name[1], name[0]);
strcpy(node->m_Name + name[0], ":");
node->m_Node.ln_Name = node->m_Name;
node->m_DosList = dlist;
AddHead((struct List *) &MSHList, &node->m_Node);
}
}
}
UnLockDosList(LDF_DEVICES | LDF_READ);
}
void
ForgetAllDevices(void)
{
struct Node *n,
*nn;
n = (struct Node *)MSHList.mlh_Head;
while (nn = n->ln_Succ) {
FreeVec(n);
n = nn;
}
NewList((struct List *) &MSHList);
}
void
Show(void)
{
if (MainWnd) {
WindowToFront(MainWnd);
return; /* already open */
}
if (SetupScreen())
Die();
if (OpenMainWindow())
Die();
FindAllDevices();
SetGadgetAttrM(GDX_HANDLERS, GTLV_Labels, (ULONG) &MSHList);
}
void
ShowParm(void)
{
if (ParmWnd) {
WindowToFront(ParmWnd);
return; /* already open */
}
if (OpenParmWindow())
return;
/* Compensate for a bug in GadToolsBox 1.3: */
ModifyIDCMP(ParmWnd,
ParmWnd->IDCMPFlags | STRINGIDCMP | BUTTONIDCMP);
UpdateStrings();
}
void
Hide(void)
{
HideParm();
if (MainWnd) {
struct IntuiMessage *msg;
while (msg = GT_GetIMsg(MainWnd->UserPort)) {
GT_ReplyIMsg(msg);
}
}
CloseMainWindow();
CloseDownScreen();
ForgetAllDevices();
}
void
HideParm(void)
{
#if 0
if (ParmWnd) {
struct IntuiMessage *msg;
while (msg = GT_GetIMsg(ParmWnd->UserPort)) {
GT_ReplyIMsg(msg);
}
}
#endif
CloseParmWindow();
}
struct MSHNode *
GetNode(struct MinList *l, int num)
{
struct Node *n,
*nn;
n = (struct Node *)l->mlh_Head;
while (num > 0 && (nn = n->ln_Succ)) {
num--;
n = nn;
}
return n;
}
void
DeselectHandler(void)
{
HandlerDList = NULL;
}
void
SelectHandler(struct MSHNode *node)
{
struct DosList *dl;
struct FileSysStartupMsg *fssm;
DeselectHandler();
HandlerName = node->m_Node.ln_Name;
dl = node->m_DosList;
HandlerDList = dl;
fssm = (struct FileSysStartupMsg *)BADDR(dl->dol_misc.dol_handler.dol_Startup);
DevName = ((char *)BADDR(fssm->fssm_Device)) + 1;
DevFlags = fssm->fssm_Flags;
DevUnit = fssm->fssm_Unit;
SetStringDefaults();
}
void
SetGadgetAttrM(int id, ULONG tag, ULONG value)
{
GT_SetGadgetAttrs(MainGadgets[id], MainWnd, NULL,
tag, value,
TAG_END);
}
void
SetGadgetAttrP(int id, ULONG tag, ULONG value)
{
if (ParmWnd) {
GT_SetGadgetAttrs(ParmGadgets[id], ParmWnd, NULL,
tag, value,
TAG_END);
}
}
void
UpdateString(int id)
{
char newstring[80];
iton(newstring, sizeof newstring, Parameters[id]);
SetGadgetAttrP(id, GTST_String, (ULONG)newstring);
}
void
UpdateStrings(void)
{
int i;
if (!ParmWnd) {
return;
}
for (i = 0; i < GDX_OK; i++) { /* 0 == GDX_BPS */
UpdateString(i);
}
}
void
MotorOff(void)
{
TDReq->iotd_Req.io_Command = TD_MOTOR;
TDReq->iotd_Req.io_Length = 0;
DoIO((struct IORequest *)TDReq);
}
int
IgnoreAbortRetry(char *fmt, ...)
{
static struct EasyStruct er0 = {
sizeof er0, 0, PanicString,
NULL,
"Abort|Retry|Ignore"
};
struct EasyStruct er;
va_list va;
MotorOff();
er = er0;
er.es_TextFormat = fmt;
va_start(va, fmt);
return EasyRequestArgs(MainWnd, &er, NULL, va);
va_end(va) /* produces error if it doesn't expand to empty */
}
int
Confirm(char *fmt, char *buttons, ...)
{
static struct EasyStruct er0 = {
sizeof er0, 0, "MSH Format",
NULL,
NULL
};
struct EasyStruct er;
va_list va;
er = er0;
er.es_TextFormat = fmt;
er.es_GadgetFormat = buttons;
va_start(va, buttons);
return EasyRequestArgs(MainWnd, &er, NULL, va);
va_end(va) /* produces error if it doesn't expand to empty */
}
/*
* Look through incoming messages to see if the user is playing
* with the gadgets. If so, ask if she wants to stop formatting.
*/
int
CheckCancel(void)
{
if (MainWnd) {
struct IntuiMessage *msg, *next;
msg = (struct IntuiMessage *)MainWnd->UserPort->mp_MsgList.lh_Head;
while (next = (struct IntuiMessage *)msg->ExecMessage.mn_Node.ln_Succ) {
if (msg->Class & (IDCMP_GADGETUP | IDCMP_GADGETDOWN |
IDCMP_CLOSEWINDOW)) {
Remove(&msg->ExecMessage.mn_Node);
ReplyMsg(&msg->ExecMessage);
MotorOff();
Break = Confirm("Stop formatting?", "Stop|Continue");
return Break;
}
msg = next;
}
}
return 0;
}
void
Title(char *fmt, int t, int s)
{
static char buf[80];
sprintf(buf, fmt, t, s);
SetWindowTitles(MainWnd, buf, (char *)-1);
}
byte *
MaybeWrite(byte *block)
{
while (Break == 0 &&
block >= (DiskTrack + TrackSize)) {
char *msg;
int t,
s;
t = Track / NSIDES;
s = Track % NSIDES;
top:
CheckCancel();
if (Break)
break;
Title("Writing cylinder %3d side %d...", t, s);
TDReq->iotd_Req.io_Command = TD_FORMAT;
TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
TDReq->iotd_Req.io_Length = TrackSize;
TDReq->iotd_Req.io_Offset = TrackSize * Track;
DoIO((struct IORequest *)TDReq);
if (TDReq->iotd_Req.io_Error) {
msg = "Write";
goto error;
}
TDReq->iotd_Req.io_Command = CMD_UPDATE;
DoIO((struct IORequest *)TDReq);
if (TDReq->iotd_Req.io_Error) {
msg = "Update";
goto error;
}
TDReq->iotd_Req.io_Command = CMD_CLEAR;
DoIO((struct IORequest *)TDReq);
Title("Reading cylinder %3d side %d...", t, s);
TDReq->iotd_Req.io_Command = CMD_READ;
TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
TDReq->iotd_Req.io_Length = TrackSize;
TDReq->iotd_Req.io_Offset = TrackSize * Track;
DoIO((struct IORequest *)TDReq);
if (TDReq->iotd_Req.io_Error) {
msg = "Read";
error:
Break = IgnoreAbortRetry("%s error %ld on\ncylinder %ld side %ld.\n",
msg, TDReq->iotd_Req.io_Error, t, s);
if (Break == 2) {
Break = 0;
goto top;
}
}
setmem(DiskTrack, (int) TrackSize, 0);
Track++;
if ((block -= TrackSize) < DiskTrack)
block = DiskTrack;
}
return block;
}
int
DoFormat(void)
{
struct MsgPort *port;
byte *diskBlock;
char *title;
int i;
Break = 0;
title = MainWnd->Title;
if (!(port = CreatePort(NULL, 0L))) {
DisplayBeep(NULL);
goto abort1;
}
if (!(TDReq = (struct IOExtTD *)CreateExtIO(port, (long) sizeof(*TDReq)))) {
DisplayBeep(NULL);
goto abort2;
}
if (OpenDevice(DevName, DevUnit, (struct IORequest *)TDReq, 0L)) {
Confirm("Cannot OpenDevice %s", AbortString, DevName);
goto abort3;
}
TrackSize = BPS * SPT;
Track = FIRSTCYL * NSIDES;
EndTrack = Track + NSIDES * NCYLS;
if ((DiskTrack = AllocMem(TrackSize,
MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)) == NULL) {
Confirm("No memory for track buffer\n(%ld bytes of chipmem)", NULL, TrackSize);
goto abort4;
}
CopyMem((char *)BootBlock, DiskTrack, (long) sizeof (BootBlock));
PutWord(DiskTrack + 0x0b, BPS);
*(DiskTrack + 0x0d) = SPC;
PutWord(DiskTrack + 0x0e, RESERVED);
*(DiskTrack + 0x10) = NFATS;
PutWord(DiskTrack + 0x11, NDIRS);
PutWord(DiskTrack + 0x13, NSECTS);
*(DiskTrack + 0x15) = MEDIA;
PutWord(DiskTrack + 0x16, SPF);
PutWord(DiskTrack + 0x18, SPT);
PutWord(DiskTrack + 0x1a, NSIDES);
PutWord(DiskTrack + 0x1c, NHID);
Break = Confirm("Insert disk to be formatted in\n%s unit %ld",
"Cancel|Format",
DevName, DevUnit);
if (Break)
return 1;
if (!Inhibit(HandlerName, DOSTRUE)) {
Confirm("Cannot inhibit %s!", AbortString, HandlerName);
goto done;
}
if (FormatWhat == BOOT_ONLY) {
top:
Title("Writing bootblock only.", 0, 0);
TDReq->iotd_Req.io_Command = CMD_WRITE;
TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
TDReq->iotd_Req.io_Length = sizeof (BootBlock);
TDReq->iotd_Req.io_Offset = 0;
DoIO((struct IORequest *)TDReq);
if (TDReq->iotd_Req.io_Error) {
Break = IgnoreAbortRetry("Write error %ld!",
TDReq->iotd_Req.io_Error);
if (Break == 2) {
Break = 0;
goto top;
}
}
if (!Break) {
TDReq->iotd_Req.io_Command = CMD_UPDATE;
DoIO((struct IORequest *)TDReq);
}
goto done;
}
/* Go to first FAT */
diskBlock = MaybeWrite(DiskTrack + BPS * RESERVED);
for (i = 0; i < NFATS; i++) {
diskBlock[0] = 0xF9;
diskBlock[1] = 0xFF;
diskBlock[2] = 0xFF;
diskBlock = MaybeWrite(diskBlock + BPS * SPF); /* Next FAT */
}
/* Clear entire directory */
diskBlock = MaybeWrite(diskBlock + NDIRS * MS_DIRENTSIZE);
MaybeWrite(DiskTrack + TrackSize); /* Force a write */
if (FormatWhat == WHOLE_DISK) {
while (Track < EndTrack) {
MaybeWrite(DiskTrack + TrackSize); /* Write an empty track */
if (Break)
break;
}
}
done:
MotorOff();
TDReq->iotd_Req.io_Command = TD_MOTOR;
TDReq->iotd_Req.io_Length = 0;
DoIO((struct IORequest *)TDReq);
SetWindowTitles(MainWnd, title, (char *)-1);
if (!Break)
Confirm("Format finished.", OkString);
Inhibit(HandlerName, DOSFALSE);
abort5:
FreeMem(DiskTrack, TrackSize);
abort4:
CloseDevice((struct IORequest *)TDReq);
abort3:
DeleteExtIO((struct IORequest *)TDReq);
abort2:
DeletePort(port);
abort1:;
return Break;
}
void
Recalculate(int id)
{
long mask;
mask = (id < 0)? ~0 : 1L << id;
if (mask & (1L<<GDX_SPT | 1L<<GDX_NSIDES | 1L<<GDX_NCYLS)) {
NSECTS = SPT * NSIDES * NCYLS;
UpdateString(GDX_NSECTS);
mask |= 1L<<GDX_NSECTS;
}
if (mask & (1L<<GDX_NSECTS | 1L<<GDX_SPC | 1L<<GDX_BPS)) {
/*
* Suggest a minimum value for the number of FAT sectors.
* Here we assume all sectors are to be used for clusters, which is not
* really true, but simpler, and gives a conservative value. Besides,
* the number of available sectors also depends on the FAT size, so
* the whole calculation (if done correctly) would be recursive. In
* practice, it may occasionally suggest one sector too much.
*/
long nclusters;
long nbytes;
int spf;
nclusters = MS_FIRSTCLUST + (NSECTS + SPC - 1) / SPC;
if (nclusters > 0xFF7) /* 16-bit FAT entries */
nbytes = nclusters * 2;
else /* 12-bit FAT entries */
nbytes = (nclusters * 3 + 1) / 2;
spf = (nbytes + BPS - 1) / BPS;
/* Hack for floppies */
if (spf < MS_SPF)
spf = MS_SPF;
SPF = spf;
UpdateString(GDX_SPF);
}
}
void
SetStringDefaults(void)
{
BPS = MS_BPS;
SPT = MS_SPT;
NSIDES = MS_NSIDES;
FIRSTCYL = 0;
NCYLS = 80;
RESERVED = MS_RES;
NHID = 0;
SPC = MS_SPC;
NFATS = MS_NFATS;
MEDIA = 0xF9;
NDIRS = MS_NDIRS;
if (HandlerDList) {
struct DosList *dl;
struct FileSysStartupMsg *fssm;
long *environ;
dl = HandlerDList;
fssm = (struct FileSysStartupMsg *)BADDR(dl->dol_misc.dol_handler.dol_Startup);
if ((environ = (long *)BADDR(fssm->fssm_Environ)) &&
environ[DE_TABLESIZE] >= DE_UPPERCYL) {
NSIDES = environ[DE_NUMHEADS];
SPT = environ[DE_BLKSPERTRACK];
BPS = environ[DE_SIZEBLOCK] * 4;
FIRSTCYL = environ[DE_LOWCYL];
NCYLS = environ[DE_UPPERCYL] - FIRSTCYL + 1;
}
}
Recalculate(-1);
UpdateStrings();
}
int
DoGadget(struct IntuiMessage *imsg)
{
struct Gadget *gd;
int id;
gd = (struct Gadget *) imsg->IAddress;
id = gd->GadgetID;
switch (id) {
case GD_HANDLERS:
{
struct MSHNode *n;
n = GetNode(&MSHList, imsg->Code);
SelectHandler(n);
SetGadgetAttrM(GDX_DOIT, GA_Disabled, FALSE);
SetGadgetAttrM(GDX_OPTIONS, GA_Disabled, FALSE);
}
break;
case GD_FMT_WHAT:
FormatWhat = imsg->Code;
break;
case GD_OPTIONS:
ShowParm();
return 2;
case GD_DOIT:
DoFormat();
break;
case GD_CANCEL:
return DONE_DONE;
case GD_BPS:
case GD_SPT:
case GD_NSIDES:
case GD_FIRSTCYL:
case GD_NCYLS:
case GD_SPC:
case GD_RESERVED:
case GD_NFATS:
case GD_NDIRS:
case GD_NSECTS:
case GD_MEDIA:
case GD_SPF:
case GD_NHID:
id -= GD_BPS - GDX_BPS; /* convert to array index */
Parameters[id] = ntoi(((struct StringInfo *)gd->SpecialInfo)->Buffer);
Recalculate(id);
break;
case GD_OK:
return DONE_HIDEP;
}
return 0;
}
struct IntuiMessage *
Safe_GT_GetIMsg(struct Window *w)
{
if (w)
return GT_GetIMsg(w->UserPort);
return NULL;
}
void
MainLoop(void)
{
long waitmask;
long mainmask;
long parmmask;
long mask;
int done;
top:
done = 0;
if (MainWnd)
mainmask = 1L << MainWnd->UserPort->mp_SigBit;
else
mainmask = 0;
if (ParmWnd)
parmmask = 1L << ParmWnd->UserPort->mp_SigBit;
else
parmmask = 0;
waitmask = mainmask | parmmask | SIGBREAKF_CTRL_C;
while (!done) {
mask = Wait(waitmask);
if (mask & SIGBREAKF_CTRL_C) {
done = DONE_DONE;
break;
}
if (mask & (mainmask | parmmask)) {
struct IntuiMessage *imsg;
while ((imsg = Safe_GT_GetIMsg(MainWnd)) ||
(imsg = Safe_GT_GetIMsg(ParmWnd))) {
switch (imsg->Class) {
case IDCMP_CLOSEWINDOW:
if (imsg->IDCMPWindow == MainWnd) {
done = DONE_DONE;
} else {
done = DONE_HIDEP;
}
break;
case IDCMP_GADGETDOWN:
case IDCMP_GADGETUP:
done = DoGadget(imsg);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(imsg->IDCMPWindow);
GT_EndRefresh(imsg->IDCMPWindow, TRUE);
break;
}
GT_ReplyIMsg(imsg);
if (done & DONE_HIDEP) {
HideParm();
goto top;
}
}
}
if (done & DONE_RESET) {
goto top;
}
}
}
void chkabort(void) {} /* DICE specific. */
int
main(int argc, char **argv)
{
OpenAll(argc, argv);
MainLoop();
Die();
return 0;
}
#ifndef WORKBENCH_STARTUP_H
#include <workbench/startup.h>
#endif
int
wbmain(struct WBStartup *wbs)
{
int rc;
long lock;
if (wbs->sm_ArgList)
lock = CurrentDir(wbs->sm_ArgList->wa_Lock);
rc = main(0, (char **)wbs);
if (wbs->sm_ArgList)
CurrentDir(lock);
return rc;
}